package ifm4j.core;

import java.util.Collection;
import java.util.LinkedList;

import org.w3c.dom.Element;

import ifm4j.collections.treeCollections.INonRoot;
import ifm4j.collections.treeCollections.TreeCollectionException;
import ifm4j.collections.treeCollections.TreeNode;
import ifm4j.collections.treeCollections.TreeObject;
import ifm4j.collections.treeCollections.factories.TreeNodeFactory;
//import ifm4j.core.arguments.FeatureNameChangedArgs;
import ifm4j.core.featureModelInteraface.IFeature;
//import ifm4j.core.shapes.FMRectangle;
import ifm4j.utils.Identifier;

public class FeatureTreeNode extends TreeNode implements IFeature {
	public static final TreeNodeFactory FACTORY = new TreeNodeFactory(FeatureTreeNode.class.getName()) {

		@Override
		public FeatureTreeNode constructNewInstance(Identifier id, Object[] args) {
			if (args == null || args.length != 1
					|| !(args[0] instanceof String)) {
				return new FeatureTreeNode(id);
			}

			String featureName = (String) args[0];
			FeatureTreeNode node = new FeatureTreeNode(id);
			node.featureName = featureName;
			return node;
		}

		@Override
		/**
		 * XML parser
		 * 
		 * @param xelem
		 * @param obj
		 * @throws TreeCollectionException
		 */
		public void xmlParser(Element elem, TreeObject treeObject) {
			if (!(treeObject instanceof FeatureTreeNode)) {
				return;
			}
			FeatureTreeNode newNode = (FeatureTreeNode) treeObject;

			newNode.featureName = elem.getAttribute(XML_NODE_NAME);
			newNode.annotation = elem.getAttribute(XML_ANNOTATION);

//			newNode.rectangle = FMRectangle.parseXElem(elem);
		}

	};

	private static final String XML_NODE_NAME = "NodeName";

	private static final String XML_ANNOTATION = "Annotation";

	private String featureName;

	private String annotation;

//	private FMRectangle rectangle;

	/**
	 * Get identifier
	 * 
	 * @param id
	 */
	public FeatureTreeNode(Identifier id) {
		super(id);
		featureName = FeatureModel.STRING_EMPTY;
		annotation = FeatureModel.STRING_EMPTY;

//		rectangle = new FMRectangle();

	}

	/**
	 * Get Parent Feature
	 * 
	 * @return
	 */
	public IFeature getParentFeature() {
		return this.getGroupRelationshipParent().getParentNode();
	}

	public FeatureTreeGroupRelationship getGroupRelationshipParent() {
		return (FeatureTreeGroupRelationship) this.parent;
	}

	/**
	 * Get feature name
	 */
	@Override
	public String getFeatureName() {
		return this.featureName;
	}

	/**
	 * Set feature name
	 */
	public void setFeatureName(String featureName) {
//		FeatureNameChangedArgs args = new FeatureNameChangedArgs(this, featureName);
//		this.treeOwner.beforeProcess(this, args);
		this.featureName = featureName;
//		this.treeOwner.afterProcess(this, args);
	}

	/**
	 * Get annotation.
	 */
	@Override
	public String getAnnotation() {
		return this.annotation;
	}

	/**
	 * Set annotation
	 */
	public void setAnnotation(String annotation) {
		this.annotation = annotation;
	}

	/**
	 * Get properties
	 */
	@Override
	public Collection<FeatureNodeProperty> getProperties() {
		LinkedList<FeatureNodeProperty> properties = new LinkedList<FeatureNodeProperty>();
		for (INonRoot child : this.children.values()) {
			if (child instanceof FeatureNodeProperty) {
				properties.add((FeatureNodeProperty) child);
			}
		}
		return properties;
	}

	/**
	 * Get Feature Tree Nodes
	 */
	@Override
	public Collection<FeatureTreeNode> getChildrenNodes() {
		LinkedList<FeatureTreeNode> nodes = new LinkedList<FeatureTreeNode>();
		for (FeatureTreeGroupRelationship gRelationship : this
				.getChildrenGroupRelationship()) {
			nodes.addAll(gRelationship.getChildrenNodes());
		}
		return nodes;
	}

	/**
	 * get children group relationship
	 */
	@Override
	public Collection<FeatureTreeGroupRelationship> getChildrenGroupRelationship() {
		LinkedList<FeatureTreeGroupRelationship> gRelationshipes = new LinkedList<FeatureTreeGroupRelationship>();
		for (INonRoot child : this.children.values()) {
			if (child instanceof FeatureTreeGroupRelationship) {
				gRelationshipes.add((FeatureTreeGroupRelationship) child);
			}
		}
		return gRelationshipes;
	}

//	/**
//	 * Get shape
//	 */
//	@Override
//	public FMRectangle getShape() {
//		return this.rectangle;
//	}

//	/**
//	 * Set shape
//	 */
//	@Override
//	public void setShape(FMRectangle shape) {
//		this.rectangle = shape;
//	}

	/**
	 * @throws TreeCollectionException
	 * 
	 */
	@Override
	public Element toXElem() throws TreeCollectionException {
		Element xelem = super.toXElem();
		xelem.setAttribute(XML_NODE_NAME, featureName);
		xelem.setAttribute(XML_ANNOTATION, annotation);

//		if (this.rectangle != null) {
//			rectangle.toXElem(xelem);
//		}
		return xelem;
	}

	@Override
	public boolean equals(Object obj) {
		boolean flag = super.equals(obj);
		if (flag == false) {
			return flag;
		}
		if (!(obj instanceof FeatureTreeNode)) {
			return false;
		}

		FeatureTreeNode featureNode = (FeatureTreeNode) obj;
		return this.featureName.equals(featureNode.featureName)
				&& this.annotation.equals(featureNode.annotation);
//				&& this.rectangle.equals(featureNode.rectangle);
	}

}